package com.qfedu.openplateform.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.qfedu.openplateform.cache.service.CacheService;
import com.qfedu.openplateform.common.constans.ExceptionDict;
import com.qfedu.openplateform.common.entity.ResponseData;
import com.qfedu.openplateform.gateway.config.ApplicationContextHolder;
import org.springframework.context.ApplicationContext;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 幂等过滤器
 *
 * 幂等就是 同样的参数 我们值处理一次，如果请求多次 则拦截
 *
 * /sztest?time=2021-08-27 10:59:39sign=A23B2AC0D7AA2CF89C825BB596140D9A&token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTYzMDAzMjc5MiwiZXhwIjoxNjMwMDM2MzkyLCJ1c2VybmFtZSI6ImFkbWluIn0.8h1OyNVuSNn0MuS0CWpogz17Ttxr8frIIhMr-SOpuOo
 *
 * sign 就是对所有请求参数的 一个标记
 *
 * 我们要做的就是每次接受请求 都去 redis  setnx 查看该 sign 是否存在，如果存则 拦截，不存在则 放行，并在 redis 中记录改 sign
 *
 *
 * 幂等 要根据 请求方法配置 是否需要幂等来处理 （有些方法不需要幂等 去后台管理应用中查询） 暂时不做
 *
 */

public class IdempotentFilter implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String requestSign = request.getParameter("sign");
        ApplicationContext applicationContext = ApplicationContextHolder.getApplicationContext();
        CacheService cacheService = applicationContext.getBean(CacheService.class);
        boolean setNx = cacheService.setNx(requestSign + "_sign", requestSign, 60 * 60 * 1000);
        if (!setNx) {
            response.setContentType("application/json;charset=utf-8");
            ResponseData bean = new ResponseData();
            bean.setCode(ExceptionDict.SYSTEMPARAM_IDEMPOTENTS_ERROR);
            bean.setMessage("签名失效");
            try {
                response.getWriter().println(JSON.toJSONString(bean));
            } catch (JsonProcessingException ex) {
                ex.printStackTrace();
            }
        }
        return setNx;
    }
}
